package com.dc.web.controller;


import com.dc.constant.MessageConstant;
import com.dc.dao.*;
import com.dc.entity.*;
import com.dc.exception.ServiceException;
import com.dc.model.AjaxResult;
import com.dc.model.PageListBody;
import com.dc.utils.DateUtils;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;


@Api(tags = "5-打砂除锈-0-打砂房分段打砂")
@RestController
@RequestMapping("/api/calibration_house_sand")
@Slf4j
public class CalibrationHouseSandController {

    @Resource
    CalibrationHouseSandDao calibrationHouseSandDao;

    @Resource
    CalibrationHouseSandChildDao calibrationHouseSandChildDao;

    @Resource
    ShipDao shipDao;

    @GetMapping("/list")
    public AjaxResult list(PageListBody body) {

        Integer pageNumber = body.getPageNumber();
        pageNumber = ObjectUtils.defaultIfNull(pageNumber, 1);
        Integer pageSize = body.getPageSize();
        pageSize = ObjectUtils.defaultIfNull(pageSize, 20);

        PageRequest pageRequest = PageRequest.of(pageNumber - 1, pageSize);

        Page<CalibrationHouseSandEntity> all = calibrationHouseSandDao.findAll(pageRequest);

        all.getContent().forEach(t-> {
            t.setShipId(t.getShip().getId());
            t.setShipName(t.getShip().getName());
        });

        return AjaxResult.success(all);
    }

    @GetMapping("/{id}")
    public AjaxResult show(@PathVariable("id") Long id) {
        Optional<CalibrationHouseSandEntity> optional = calibrationHouseSandDao.findById(id);
        CalibrationHouseSandEntity entity = null;
        if (optional.isPresent()) {
            entity = optional.get();
            entity.setShipId(entity.getShip().getId());
            entity.setShipName(entity.getShip().getName());
            return AjaxResult.success(entity);
        } else {
            return AjaxResult.error("数据不存在! id = " + id);
        }
    }

    @PostMapping()
    public AjaxResult add(@RequestBody CalibrationHouseSandEntity entity) {
        entity.setId(null);
        Optional<ShipEntity> optionalShip = shipDao.findById(entity.getShipId());
        if(!optionalShip.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_SHIP_MISSING);
        }
        ShipEntity ship = optionalShip.get();
        entity.setShip(ship);

        // 动态计算
        calc(entity);

        CalibrationHouseSandEntity save = calibrationHouseSandDao.save(entity);
        save.setShipName(ship.getName());
        return AjaxResult.success(save);
    }

    @PutMapping("/{id}")
    public AjaxResult update(@PathVariable("id") Long id, @RequestBody CalibrationHouseSandEntity entity) {
        Optional<CalibrationHouseSandEntity> optionalSand = calibrationHouseSandDao.findById(id);
        if(!optionalSand.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_CALIBRATION_MISSION);
        }
        CalibrationHouseSandEntity sandEntity = optionalSand.get();

        if(!sandEntity.getShip().getId().equals(entity.getShipId())) {      // 如果ship有更换，则更新shipId，否则不更新shipID
            Optional<ShipEntity> optionalShip = shipDao.findById(entity.getShipId());
            if(!optionalShip.isPresent()) {
                throw new ServiceException(MessageConstant.ERR_SHIP_MISSING);
            }
            ShipEntity ship = optionalShip.get();
            sandEntity.setShip(ship);
        }

        //////////// 更新字段
        sandEntity.setArea(entity.getArea());
        sandEntity.setStartAir(entity.startAir);
        sandEntity.setEndAir(entity.endAir);
        ///////////

        /////////// 动态更新
        calc(sandEntity);
        //////////

        ShipEntity ship = sandEntity.getShip();

        CalibrationHouseSandEntity save = calibrationHouseSandDao.save(sandEntity);
        save.setShipId(ship.getId());
        save.setShipName(ship.getName());
        save.getInner().forEach(t -> t.setPid(save.getId()));
        return AjaxResult.success(save);
    }

    @DeleteMapping("/{id}")
    public AjaxResult delete(@PathVariable("id") Long id) {
        Optional<CalibrationHouseSandEntity> optional = calibrationHouseSandDao.findById(id);
        if (optional.isPresent()) {
            CalibrationHouseSandEntity entity = optional.get();
            List<CalibrationHouseSandChildEntity> inner = entity.getInner();

            if(ObjectUtils.isNotEmpty(inner)) {
                Collection<Long> collect = inner.stream().map(CalibrationHouseSandChildEntity::getId).collect(Collectors.toList());
                calibrationHouseSandChildDao.deleteAllById(collect);
            }
            calibrationHouseSandDao.deleteById(id);

        }
        return AjaxResult.success();
    }

    /////////////////////////////////////// child ////////////////////////////////////////////

    @GetMapping("/child/{id}")
    public AjaxResult showChild(@PathVariable("id") Long id) {
        Optional<CalibrationHouseSandChildEntity> optional = calibrationHouseSandChildDao.findById(id);
        CalibrationHouseSandChildEntity entity = null;
        if (optional.isPresent()) {
            entity = optional.get();
            entity.setPid(entity.getCalibrationHouseSandEntity().getId());
            return AjaxResult.success(entity);
        } else {
            return AjaxResult.error("数据不存在! id = " + id);
        }
    }

    @PostMapping("/child")
    public AjaxResult addChild(@RequestBody CalibrationHouseSandChildEntity entity) {
        entity.setId(null);
        Optional<CalibrationHouseSandEntity> optional = calibrationHouseSandDao.findById(entity.getPid());
        if(!optional.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_CALIBRATION_MISSION);
        }

        CalibrationHouseSandEntity calibrationHouseSandEntity = optional.get();
        entity.setCalibrationHouseSandEntity(calibrationHouseSandEntity);
        // 动态计算
        calcChild(entity);
        CalibrationHouseSandChildEntity save = calibrationHouseSandChildDao.save(entity);
        ////////////////////////////////
        // 动态计算
        calibrationHouseSandEntity.getInner().add(entity);

        calc(calibrationHouseSandEntity);

        // 查询父，进行计算
        calibrationHouseSandDao.save(calibrationHouseSandEntity);
        return AjaxResult.success(save);
    }

    @PutMapping("/child/{id}")
    public AjaxResult updateChild(@PathVariable("id") Long id, @RequestBody CalibrationHouseSandChildEntity entity) {
        entity.setId(id);
        Optional<CalibrationHouseSandEntity> optional = calibrationHouseSandDao.findById(entity.getPid());
        if(!optional.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_CALIBRATION_MISSION);
        }
        CalibrationHouseSandEntity calibrationHouseSandEntity = optional.get();
        entity.setCalibrationHouseSandEntity(calibrationHouseSandEntity);
        // 动态计算
        calcChild(entity);

        CalibrationHouseSandChildEntity save = calibrationHouseSandChildDao.save(entity);
        ///////////////////////////////////////
        // 动态计算
        calc(calibrationHouseSandEntity);

        // 查询父，进行计算
        calibrationHouseSandDao.save(calibrationHouseSandEntity);

        save.setPid(entity.getPid());
        return AjaxResult.success(save);
    }

    @DeleteMapping("/child/{id}")
    public AjaxResult deleteChild(@PathVariable("id") Long id) {
        Optional<CalibrationHouseSandChildEntity> childEntityOptional = calibrationHouseSandChildDao.findById(id);
        if(!childEntityOptional.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_CALIBRATION_MISSION);
        }
        CalibrationHouseSandChildEntity childEntity = childEntityOptional.get();
        CalibrationHouseSandEntity calibrationPaintHouseEntity = childEntity.getCalibrationHouseSandEntity();
        calibrationPaintHouseEntity.getInner().remove(childEntity);
        // 动态计算
        calc(calibrationPaintHouseEntity);

        calibrationHouseSandDao.save(calibrationPaintHouseEntity);

        calibrationHouseSandChildDao.deleteById(id);
        return AjaxResult.success();
    }

    private CalibrationHouseSandChildEntity calcChild(CalibrationHouseSandChildEntity entity) {
        // powerByHour = (endTime-startTime)*num*power*24
        if(ObjectUtils.isEmpty(entity.endTime) || ObjectUtils.isEmpty(entity.startTime)) {
            entity.powerByHour = 0.;
            return entity;
        }
        entity.powerByHour = DateUtils.differentDaysDoubleByMillisecond(entity.startTime, entity.endTime) * entity.num * entity.power * 24;
        return entity;
    }

    private CalibrationHouseSandEntity calc(CalibrationHouseSandEntity entity) {

        List<CalibrationHouseSandChildEntity> inner = entity.getInner();



        // powers;      // 耗电能(kwh) 动态计算
        try {
            double power = inner.stream()
//                .peek(t -> t.powerByHour = DateUtils.differentDaysDoubleByMillisecond(t.startTime, t.endTime) * 24 * t.num * t.power)
                    .mapToDouble(CalibrationHouseSandChildEntity::getPowerByHour)
                    .reduce(Double::sum)
                    .orElse(0.);
            entity.power = power;
        } catch (Exception e) {
            entity.power = 0.;
        }

        // powerByUnit
        try {
            entity.powerByUnit = entity.power / entity.area;
        } catch (Exception e) {
            entity.powerByUnit = 0.;
        }

        // air
        try {
            entity.air = entity.endAir - entity.startAir;
        } catch (Exception e) {
            entity.air = 0.;
        }

        // airByUnit
        try {
            entity.airByUnit = entity.air / entity.area;
        } catch (Exception e) {
            entity.airByUnit = 0.;
        }

        return entity;
    }
}
